package com.cencat.common.exception;

import com.cencat.common.enums.ErrorCode;

/**
 * 业务异常类
 * 用于处理业务逻辑中的异常情况
 * 
 * @author cencat
 * @since 2024-01-01
 */
public class BusinessException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    /**
     * 错误码
     */
    private final Integer code;

    /**
     * 错误消息
     */
    private final String message;

    /**
     * 错误码枚举
     */
    private final ErrorCode errorCode;

    /**
     * 构造函数（使用错误码枚举）
     * 
     * @param errorCode 错误码枚举
     */
    public BusinessException(ErrorCode errorCode) {
        super(errorCode.getMessage());
        this.errorCode = errorCode;
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
    }

    /**
     * 构造函数（使用错误码枚举和自定义消息）
     * 
     * @param errorCode 错误码枚举
     * @param message 自定义错误消息
     */
    public BusinessException(ErrorCode errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
        this.code = errorCode.getCode();
        this.message = message;
    }

    /**
     * 构造函数（使用错误码枚举、自定义消息和原因）
     * 
     * @param errorCode 错误码枚举
     * @param message 自定义错误消息
     * @param cause 异常原因
     */
    public BusinessException(ErrorCode errorCode, String message, Throwable cause) {
        super(message, cause);
        this.errorCode = errorCode;
        this.code = errorCode.getCode();
        this.message = message;
    }

    /**
     * 构造函数（使用自定义错误码和消息）
     * 
     * @param code 错误码
     * @param message 错误消息
     */
    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
        this.message = message;
        this.errorCode = ErrorCode.getByCode(code);
    }

    /**
     * 构造函数（使用自定义错误码、消息和原因）
     * 
     * @param code 错误码
     * @param message 错误消息
     * @param cause 异常原因
     */
    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
        this.message = message;
        this.errorCode = ErrorCode.getByCode(code);
    }

    /**
     * 获取错误码
     * 
     * @return 错误码
     */
    public Integer getCode() {
        return code;
    }

    /**
     * 获取错误消息
     * 
     * @return 错误消息
     */
    @Override
    public String getMessage() {
        return message;
    }

    /**
     * 获取错误码枚举
     * 
     * @return 错误码枚举
     */
    public ErrorCode getErrorCode() {
        return errorCode;
    }

    /**
     * 创建参数错误异常
     * 
     * @param message 错误消息
     * @return BusinessException
     */
    public static BusinessException paramError(String message) {
        return new BusinessException(ErrorCode.PARAM_ERROR, message);
    }

    /**
     * 创建数据不存在异常
     * 
     * @param message 错误消息
     * @return BusinessException
     */
    public static BusinessException dataNotExists(String message) {
        return new BusinessException(ErrorCode.DATA_NOT_EXISTS, message);
    }

    /**
     * 创建数据已存在异常
     * 
     * @param message 错误消息
     * @return BusinessException
     */
    public static BusinessException dataAlreadyExists(String message) {
        return new BusinessException(ErrorCode.DATA_ALREADY_EXISTS, message);
    }

    /**
     * 创建操作失败异常
     * 
     * @param message 错误消息
     * @return BusinessException
     */
    public static BusinessException operationFailed(String message) {
        return new BusinessException(ErrorCode.OPERATION_FAILED, message);
    }

    /**
     * 创建权限不足异常
     * 
     * @return BusinessException
     */
    public static BusinessException permissionDenied() {
        return new BusinessException(ErrorCode.USER_PERMISSION_DENIED);
    }

    /**
     * 创建未授权异常
     * 
     * @return BusinessException
     */
    public static BusinessException unauthorized() {
        return new BusinessException(ErrorCode.UNAUTHORIZED);
    }

    /**
     * 创建租户访问被拒绝异常
     * 
     * @return BusinessException
     */
    public static BusinessException tenantAccessDenied() {
        return new BusinessException(ErrorCode.TENANT_ACCESS_DENIED);
    }
}